package com.example.selenium;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.example.selenium.core.other.WaybillU;
import com.example.selenium.domain.WaybillDto2;
import com.example.selenium.enums.BussinessEnum;
import com.example.selenium.enums.GoodsTypeEnum;
import com.example.selenium.enums.ShippingStatusEnum;
import com.example.selenium.queue.rabbitmq.confirm.ConfirmCallbackService;
import com.example.selenium.util.*;
import lombok.SneakyThrows;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.io.FileUtils;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.yaml.snakeyaml.util.UriEncoder;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 查询开始时间：2021-07-06 20:00:00,查询结束时间：2021-07-07 00:00:00
 2021-07-15 18:15:47.239  INFO 13316 --- [  restartedMain] com.example.selenium.AutomaticGrab       : 数据条目：106
 */
@SpringBootApplication
public class AutomaticGrab {
    protected static Logger logger = LoggerFactory.getLogger(AutomaticGrab.class);

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private WaybillU waybillU;

    @Autowired
    private StringRedisTemplate  stringRedisTemplate;

    private static final String LOGIN_NAME = "13926676253";
    private static final String LOGIN_PWD = "ZDwl1234*";
    private static final String LOGIN_URL = "https://apit.y2t.com/cockpit-lhk/login";
    private static final String RUN_PATH = "C:\\chromedriver_win32\\chromedriver.exe";
    private static String BILLINGSTATUS = "";
    private static Integer DATA_LENGTH = 1300; // 每页加载的数据大小
    private static Map<Integer,String> companyMap = new HashMap<>();

    /**
     * 4小时之前的运单
     */
    public static final String TOPIC_4_HOURS_BEFORE_WAYBILL="before4HoursWaybill";
    /**
     * 更新 已经开票了的运单(说明已经支付了，目的是获取拿到支付信息)
     */
    public static final String TOPIC_FINISHED_PAY="finishedPay";

    /**
     * 更新发票
     */
    public static final String TOPIC_UPDATE_INVOICE="updateForInvoice";

    /**
     *   更新3天内的运单状态
     */
    public static final String TOPIC_UPDATE_STATUS_IN_3DAYS="updateStatusIn3Days";

    public static  final String TOPIC_GET_WAYBILL_BY_ID="getWaybillById";

    private static String tips = "";


    public static void main(String[] args)  {
        ConfigurableApplicationContext applicationContext = SpringApplication.run(AutomaticGrab.class, args);
    }

    /**
     * 初始化,
     */
    public void init(){
        String cookie = getCookie();
        if(StringUtils.isEmpty(cookie)){
            toLogin();
        }
    }

    public void getAllPayList(){
        // 创建工作薄
        XSSFWorkbook workbook = new XSSFWorkbook();
        // 创建工作表
        XSSFSheet newSheet = workbook.createSheet("sheet1");
        XSSFRow rowTitle = newSheet.createRow(0);;
        rowTitle.createCell(0).setCellValue("支付单号");
        rowTitle.createCell(1).setCellValue("运单号");
        rowTitle.createCell(2).setCellValue("司机");
        rowTitle.createCell(3).setCellValue("收款账户");
        rowTitle.createCell(4).setCellValue("费用类型");
        rowTitle.createCell(5).setCellValue("实付(司机)");
        rowTitle.createCell(6).setCellValue("实收(含费)");
        rowTitle.createCell(7).setCellValue("审核状态");
        rowTitle.createCell(8).setCellValue("支付状态");
        rowTitle.createCell(9).setCellValue("申请时间");

        String url = "https://apit.y2t.com/lhk/proxy/finance/Finance/findWaybillPayDetailWithPage?proId=&companyId=383&status=2&approveStatus=3&orderNo=&beginTime=&endTime=&draw=NaN&columns%5B0%5D%5Bdata%5D=0&columns%5B0%5D%5Bname%5D=&columns%5B0%5D%5Bsearchable%5D=true&columns%5B0%5D%5Borderable%5D=false&columns%5B0%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B0%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B1%5D%5Bdata%5D=payWaybillNo&columns%5B1%5D%5Bname%5D=&columns%5B1%5D%5Bsearchable%5D=true&columns%5B1%5D%5Borderable%5D=false&columns%5B1%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B1%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B2%5D%5Bdata%5D=2&columns%5B2%5D%5Bname%5D=&columns%5B2%5D%5Bsearchable%5D=true&columns%5B2%5D%5Borderable%5D=false&columns%5B2%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B2%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B3%5D%5Bdata%5D=waybillNo&columns%5B3%5D%5Bname%5D=&columns%5B3%5D%5Bsearchable%5D=true&columns%5B3%5D%5Borderable%5D=false&columns%5B3%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B3%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B4%5D%5Bdata%5D=projectName&columns%5B4%5D%5Bname%5D=&columns%5B4%5D%5Bsearchable%5D=true&columns%5B4%5D%5Borderable%5D=false&columns%5B4%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B4%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B5%5D%5Bdata%5D=&columns%5B5%5D%5Bname%5D=&columns%5B5%5D%5Bsearchable%5D=true&columns%5B5%5D%5Borderable%5D=false&columns%5B5%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B5%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B6%5D%5Bdata%5D=6&columns%5B6%5D%5Bname%5D=&columns%5B6%5D%5Bsearchable%5D=true&columns%5B6%5D%5Borderable%5D=true&columns%5B6%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B6%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B7%5D%5Bdata%5D=7&columns%5B7%5D%5Bname%5D=&columns%5B7%5D%5Bsearchable%5D=true&columns%5B7%5D%5Borderable%5D=true&columns%5B7%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B7%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B8%5D%5Bdata%5D=payeeName&columns%5B8%5D%5Bname%5D=&columns%5B8%5D%5Bsearchable%5D=true&columns%5B8%5D%5Borderable%5D=false&columns%5B8%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B8%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B9%5D%5Bdata%5D=payeeName&columns%5B9%5D%5Bname%5D=&columns%5B9%5D%5Bsearchable%5D=true&columns%5B9%5D%5Borderable%5D=false&columns%5B9%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B9%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B10%5D%5Bdata%5D=bankNo&columns%5B10%5D%5Bname%5D=&columns%5B10%5D%5Bsearchable%5D=true&columns%5B10%5D%5Borderable%5D=false&columns%5B10%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B10%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B11%5D%5Bdata%5D=bankName&columns%5B11%5D%5Bname%5D=&columns%5B11%5D%5Bsearchable%5D=true&columns%5B11%5D%5Borderable%5D=false&columns%5B11%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B11%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B12%5D%5Bdata%5D=payType&columns%5B12%5D%5Bname%5D=&columns%5B12%5D%5Bsearchable%5D=true&columns%5B12%5D%5Borderable%5D=false&columns%5B12%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B12%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B13%5D%5Bdata%5D=13&columns%5B13%5D%5Bname%5D=&columns%5B13%5D%5Bsearchable%5D=true&columns%5B13%5D%5Borderable%5D=false&columns%5B13%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B13%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B14%5D%5Bdata%5D=14&columns%5B14%5D%5Bname%5D=&columns%5B14%5D%5Bsearchable%5D=true&columns%5B14%5D%5Borderable%5D=false&columns%5B14%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B14%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B15%5D%5Bdata%5D=approveStatus&columns%5B15%5D%5Bname%5D=&columns%5B15%5D%5Bsearchable%5D=true&columns%5B15%5D%5Borderable%5D=false&columns%5B15%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B15%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B16%5D%5Bdata%5D=status&columns%5B16%5D%5Bname%5D=&columns%5B16%5D%5Bsearchable%5D=true&columns%5B16%5D%5Borderable%5D=false&columns%5B16%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B16%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B17%5D%5Bdata%5D=createdTime&columns%5B17%5D%5Bname%5D=&columns%5B17%5D%5Bsearchable%5D=true&columns%5B17%5D%5Borderable%5D=false&columns%5B17%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B17%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B18%5D%5Bdata%5D=&columns%5B18%5D%5Bname%5D=&columns%5B18%5D%5Bsearchable%5D=true&columns%5B18%5D%5Borderable%5D=false&columns%5B18%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B18%5D%5Bsearch%5D%5Bregex%5D=false&start=0&length=1000&search%5Bvalue%5D=&search%5Bregex%5D=false&applyStatus=-1&_=1616568066971";
        String response = HttpClientUtil.doGet(url, null, getCookie());
        JSONArray dataList = JSONObject.parseObject(response).getJSONArray("data");
        for (int row = 0; row < dataList.size(); row++) {
            logger.info("总共有"+dataList.size()+"条，正在处理第"+(row+1)+"条");
            JSONObject payDto = dataList.getJSONObject(row);
            XSSFRow newRow = newSheet.createRow(row+1);
            newRow.createCell(0).setCellValue(payDto.getString("payWaybillNo"));
            newRow.createCell(1).setCellValue(payDto.getString("waybillNo")+"-"+payDto.getString("projectName"));
            newRow.createCell(2).setCellValue(payDto.getString("driverName")+"-"+payDto.getString("vehicleNo")+"-"+payDto.getString("driverPhone"));
            newRow.createCell(3).setCellValue(payDto.getString("payeeName")+"-"+payDto.getString("bankNo")+"-"+payDto.getString("bankName"));
            newRow.createCell(4).setCellValue(payDto.getString("payType").equals("1")?"预付":payDto.getString("payType").equals("2")?"到付":"");
            newRow.createCell(5).setCellValue(payDto.getString("realWaybillPrice"));
            newRow.createCell(6).setCellValue(payDto.getString("realAmt"));
            newRow.createCell(7).setCellValue(payDto.getString("approveStatus").equals("3")?"财务审核通过":"");
            newRow.createCell(8).setCellValue(payDto.getString("status").equals("2")?"支付成功":"");
            newRow.createCell(9).setCellValue(payDto.getString("createdTime").substring(0,19).replace("T"," "));
            logger.info("第"+(row+1)+"条生成完毕！");
        }
        //写入文件
        try {
            workbook.write(new FileOutputStream(new File("E:\\zhifuliebiaoExcel\\pay.xlsx")));
            workbook.close();
            logger.info("excel生成完毕");
        } catch (Exception ex) {
            System.out.println(ex.getMessage());
        }
    }



//***************************************************登录相关**********************************************************

    /**
     * 获取driver
     * @return
     */
    public static WebDriver getDriver(){
        ChromeOptions options = new ChromeOptions();
        System.setProperty("webdriver.chrome.driver", RUN_PATH);
        options.setExperimentalOption("excludeSwitches", Arrays.asList("enable-automation"));
        WebDriver driver = new ChromeDriver(options);
        driver.manage().window().setSize(new Dimension(1360, 850));
        return driver;
    }

    /**
     * 自动登录
     * @throws InterruptedException
     */
    private static void autoLogin(WebDriver driver) throws InterruptedException {
        // http://merchant.yxtweb.com/index.html
        // String jsStr = "window.alert(\"请尽快完成验证码和用户名的输入！\")";
        // ((JavascriptExecutor) driver).executeScript(jsStr);
        boolean isNext = true;

        do {
            driver.get(LOGIN_URL);
            Thread.sleep(1000*5);

            WebElement isAlive = driver.findElement(By.xpath("//*[@id=\"userName\"]"));
            if (null == isAlive) {
                 Thread.sleep(1000*30);
                 continue;
            }

            sendkeys(LOGIN_NAME, driver.findElement(By.xpath("//*[@id=\"userName\"]")));

            sendkeys(LOGIN_PWD, driver.findElement(By.xpath("//*[@id=\"passWord\"]")));
            Thread.sleep(1000 * 5);
            logger.info("请输入用户名验证码！");
            // 截图验证码
            WebElement checkCodeE = driver.findElement(By.xpath("//*[@id=\"checkCode\"]"));
            File src = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
            String vcodeimgPath = "C:\\verifyCode\\test.png";
            try {
                FileUtils.copyFile(captureElement(src, checkCodeE), new File(vcodeimgPath));
            } catch (IOException e) {
                e.printStackTrace();
            }

            System.err.println("------------------------------------------------------------------------------------");

            // 这里开始识别验证码
            String vCodeResult = OcrUtils.imgOcr(vcodeimgPath).replaceAll(" ", "").replaceAll("\n", "");
            System.err.println("vCodeResult=" + vCodeResult);
            String inputVCodeJs = "document.getElementById(\"verFiCode\").value='" + vCodeResult + "';";
            System.err.println("inputVCodeJs=" + inputVCodeJs);
            ((JavascriptExecutor) driver).executeScript(inputVCodeJs);
            // driver.findElement(By.xpath("//*[@id=\"verFiCode\"]")).sendKeys(vCodeResult.replaceAll("
            // ", ""));

            Thread.sleep(1000 * 5);

            driver.findElement(By.xpath("//*[@id=\"login\"]")).click();
            Thread.sleep(1000 * 3);

            // 错误messges如果出现表明需要进入下一次登录，因为错误了
            WebElement showMassage = driver.findElement(By.xpath("//*[@id=\"showMassage\"]"));
            if (null != showMassage && showMassage.isDisplayed()) {
                isNext = true;
            } else {
                isNext = false;
                WebElement isOnLine = driver.findElement(By.xpath("//*[@id=\"kickedNo\"]"));
                if (null != isOnLine && isOnLine.isDisplayed() && isOnLine.isEnabled()) {
                    isOnLine.click();
                }
            }
        } while (isNext);
        logger.info("成功登录运易通，如果有出现同时在线的情况，需要特殊处理，请尽快完成处理!");
    }



    /**
     * 去登陆
     */
    public void toLogin(){
        ChromeOptions options = new ChromeOptions();
        System.setProperty("webdriver.chrome.driver", RUN_PATH);
        options.setExperimentalOption("excludeSwitches", Arrays.asList("enable-automation"));
        WebDriver driver = new ChromeDriver(options);
        driver.manage().window().setSize(new Dimension(1360, 850));
        try {
            driver.get(LOGIN_URL);
            sendkeys(LOGIN_NAME, driver.findElement(By.xpath("//*[@id=\"userName\"]")));
            sendkeys(LOGIN_PWD, driver.findElement(By.xpath("//*[@id=\"passWord\"]")));
            String jsStr = "window.alert(\"请尽快完成验证码和用户名的输入！\")";
            ((JavascriptExecutor) driver).executeScript(jsStr);
            do {
                Thread.sleep(1000 * 10);
                logger.info("请输入用户名验证码！");
            } while (LOGIN_URL.equals(driver.getCurrentUrl()));
            logger.info("成功登录运易通，如果有出现同时在线的情况，需要特殊处理，请尽快完成处理!");
            Thread.sleep(1000 * 5);

            // 获取cookie
            setLoginCookie(driver);
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    /**
     * 获取cookie
     * @param webDriver
     */
    public  void setLoginCookie(WebDriver webDriver){
        String jsessionIdCookie = "";
        String sinoSSOCookie = "";
        Set<Cookie> cookies = webDriver.manage().getCookies();

        Iterator<Cookie> iterator = cookies.iterator();
        while (iterator.hasNext()){
            Cookie next = iterator.next();
            if(next.getName().equalsIgnoreCase("JSESSIONID")){
                jsessionIdCookie =next.getValue();
                continue;
            }
            if(next.getName().equalsIgnoreCase("SinoSSO")){
                sinoSSOCookie =next.getValue();
                continue;
            }
        }
        redisUtil.set("y2tLoginCookie","JSESSIONID="+jsessionIdCookie+"; SinoSSO="+sinoSSOCookie);
    }


    //**************************************************运单相关********************************************************************
    /**
     * 获取实时运单
     * @return
     * @throws ParseException
     * @throws InterruptedException
     */
    public List<WaybillDto2> getMomentWaybillList() throws ParseException, InterruptedException {

        // 获取所有公司名称
        Integer result = getCompany();
        if(result==-1){
            System.err.println("原有的cookie已失效，准备执行自动登录");
            loginProcessor();
            Thread.sleep(1000 * 5);
        }

        String currentTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        getAllWaybillListByTime(waybillU.getLastQueryTime(),currentTime);
        return null;
    }


    /**
     * 获取支付记录
     * @param waybillId
     */
    @SneakyThrows
    public  void getPayDetail(String waybillId,WaybillDto2 build){
        String requestUrl = "https://apit.y2t.com/lhk/proxy/waybillmanagement/queryPayDetail?wayBillId="+waybillId+"&_="+new Date().getTime();
        String result = HttpClientUtil.doGet(requestUrl,null,getCookie());
        logger.info("getPayDetail result："+result);
        if(StringUtils.isNotEmpty(result)){
            JSONArray payArray = JSONArray.parseArray(result);
            if(payArray!=null && payArray.size()>0){
                for (int i = 0; i < payArray.size(); i++) {
                    JSONObject payJson =(JSONObject)payArray.get(i);
                    if(payJson.getString("status").equals("2")){
                        String sysNo = payJson.getString("sysNo");
                        build.setPayWaybillNo(payJson.getString("payWaybillNo"));
                        getTransOrderMain(sysNo,build);
                    }
                }
            }
        }
    }
    /**
     * 获取交易订单Main
     */
    @SneakyThrows
    public  String getTransOrderMain(String sysNo,WaybillDto2 build){
        String requestUrl = "https://apit.y2t.com/lhk/proxy/settlement/Finance/getTransOrderMain?sysNo="+sysNo+"&applyStatus=-1&_="+new Date().getTime();
        String result =  HttpClientUtil.doGet(requestUrl, null, getCookie());
        logger.info("getTransOrderMain result："+result);
        if(StringUtils.isNotEmpty(result)){
            JSONObject mainJson = JSONObject.parseObject(result);
            if(mainJson.getString("status").equals("true")){
                JSONArray dataArray = mainJson.getJSONArray("data");
                if(dataArray!=null && dataArray.size()>0){
                    JSONArray payRecordArray = new JSONArray();
                    JSONObject payRecordObj = new JSONObject();
                    for (int i = 0; i < dataArray.size(); i++) {
                        JSONObject json =((JSONObject) dataArray.get(i)).getJSONObject("transOrderMain");

                        if(StringUtils.isNotEmpty(json.getString("transTime"))){
                            String newTime = json.getString("transTime").substring(0,19).replaceAll("T"," ");
                            String transTime = UTCToCST(newTime,"yyyy-MM-dd HH:mm:ss");
                            payRecordObj.put("orderDate",transTime);
                        }

                        payRecordObj.put("channelFlowNo",build.getPayWaybillNo()); // 支付流水号 等于运易通的支付单号
                        if(json.getString("billType").equals("1")){// 手续费
                            payRecordObj.put("feeAmt",json.getString("amt"));
                            payRecordObj.put("feeHostFlowNo",json.getString("hostFlowNo"));
                        }else if(json.getString("billType").equals("0")){ // 运费相关
                            build.setReciveName(json.getString("recAccountName"));
                            build.setReciveCardNo(json.getString("recAccountNo"));
                            build.setReciveBankeName(json.getString("recBankName"));

                            payRecordObj.put("payAmt",json.getString("amt"));
                            payRecordObj.put("payHostFlowNo",json.getString("hostFlowNo"));
                        }
                    }
                    payRecordArray.add(payRecordObj);
                    // 如果有支付记录，那么对应我们系统里面，运单一定是已审核
                    if(payRecordArray!=null&&payRecordArray.size()>0){
                        build.setWaybillStatus(ShippingStatusEnum.CODE_4.getDesc());
                    }
                    build.setPayRecord(JSONObject.toJSONString(payRecordArray));
                }
            }
        }
        return result;
    }

    /**
     * 获取运单列表
     * @param waybillStatus  运单状态：0 ：待起运 ，1：已起运 ，2：已到达 ，3：已回单
     * @throws ParseException
     */
    public  List<WaybillDto2> getWaybillList(String waybillStatus,String startTime,String endTime) throws ParseException {
        startTime = UriEncoder.encode(startTime);
        endTime = UriEncoder.encode(endTime);
        String url = "https://apit.y2t.com/lhk/proxy/waybillmanagement/getWayBills?projectId=&waybillNo=&customerSystemCode=&driverName=&shippingStatus=&trackStatus=&payStatus=&billingStatus="+waybillStatus+"&bTime="+startTime+"&eTime="+endTime+"&companyId=&draw=NaN&columns%5B0%5D%5Bdata%5D=0&columns%5B0%5D%5Bname%5D=&columns%5B0%5D%5Bsearchable%5D=true&columns%5B0%5D%5Borderable%5D=false&columns%5B0%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B0%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B1%5D%5Bdata%5D=1&columns%5B1%5D%5Bname%5D=&columns%5B1%5D%5Bsearchable%5D=true&columns%5B1%5D%5Borderable%5D=false&columns%5B1%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B1%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B2%5D%5Bdata%5D=&columns%5B2%5D%5Bname%5D=&columns%5B2%5D%5Bsearchable%5D=true&columns%5B2%5D%5Borderable%5D=false&columns%5B2%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B2%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B3%5D%5Bdata%5D=&columns%5B3%5D%5Bname%5D=&columns%5B3%5D%5Bsearchable%5D=true&columns%5B3%5D%5Borderable%5D=false&columns%5B3%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B3%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B4%5D%5Bdata%5D=&columns%5B4%5D%5Bname%5D=&columns%5B4%5D%5Bsearchable%5D=true&columns%5B4%5D%5Borderable%5D=false&columns%5B4%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B4%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B5%5D%5Bdata%5D=5&columns%5B5%5D%5Bname%5D=&columns%5B5%5D%5Bsearchable%5D=true&columns%5B5%5D%5Borderable%5D=false&columns%5B5%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B5%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B6%5D%5Bdata%5D=6&columns%5B6%5D%5Bname%5D=&columns%5B6%5D%5Bsearchable%5D=true&columns%5B6%5D%5Borderable%5D=false&columns%5B6%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B6%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B7%5D%5Bdata%5D=7&columns%5B7%5D%5Bname%5D=&columns%5B7%5D%5Bsearchable%5D=true&columns%5B7%5D%5Borderable%5D=false&columns%5B7%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B7%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B8%5D%5Bdata%5D=&columns%5B8%5D%5Bname%5D=&columns%5B8%5D%5Bsearchable%5D=true&columns%5B8%5D%5Borderable%5D=false&columns%5B8%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B8%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B9%5D%5Bdata%5D=9&columns%5B9%5D%5Bname%5D=&columns%5B9%5D%5Bsearchable%5D=true&columns%5B9%5D%5Borderable%5D=false&columns%5B9%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B9%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B10%5D%5Bdata%5D=10&columns%5B10%5D%5Bname%5D=&columns%5B10%5D%5Bsearchable%5D=true&columns%5B10%5D%5Borderable%5D=false&columns%5B10%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B10%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B11%5D%5Bdata%5D=11&columns%5B11%5D%5Bname%5D=&columns%5B11%5D%5Bsearchable%5D=true&columns%5B11%5D%5Borderable%5D=false&columns%5B11%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B11%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B12%5D%5Bdata%5D=&columns%5B12%5D%5Bname%5D=&columns%5B12%5D%5Bsearchable%5D=true&columns%5B12%5D%5Borderable%5D=false&columns%5B12%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B12%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B13%5D%5Bdata%5D=remark&columns%5B13%5D%5Bname%5D=&columns%5B13%5D%5Bsearchable%5D=true&columns%5B13%5D%5Borderable%5D=false&columns%5B13%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B13%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B14%5D%5Bdata%5D=waybillNo&columns%5B14%5D%5Bname%5D=&columns%5B14%5D%5Bsearchable%5D=true&columns%5B14%5D%5Borderable%5D=false&columns%5B14%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B14%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B15%5D%5Bdata%5D=projectName&columns%5B15%5D%5Bname%5D=&columns%5B15%5D%5Bsearchable%5D=true&columns%5B15%5D%5Borderable%5D=false&columns%5B15%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B15%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B16%5D%5Bdata%5D=customerSystemCode&columns%5B16%5D%5Bname%5D=&columns%5B16%5D%5Bsearchable%5D=true&columns%5B16%5D%5Borderable%5D=false&columns%5B16%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B16%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B17%5D%5Bdata%5D=driverName&columns%5B17%5D%5Bname%5D=&columns%5B17%5D%5Bsearchable%5D=true&columns%5B17%5D%5Borderable%5D=false&columns%5B17%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B17%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B18%5D%5Bdata%5D=vehicleNo&columns%5B18%5D%5Bname%5D=&columns%5B18%5D%5Bsearchable%5D=true&columns%5B18%5D%5Borderable%5D=false&columns%5B18%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B18%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B19%5D%5Bdata%5D=driverPhone&columns%5B19%5D%5Bname%5D=&columns%5B19%5D%5Bsearchable%5D=true&columns%5B19%5D%5Borderable%5D=false&columns%5B19%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B19%5D%5Bsearch%5D%5Bregex%5D=false&start=0&length="+ DATA_LENGTH +"&search%5Bvalue%5D=&search%5Bregex%5D=false&_=1609528285201";
        String response = HttpClientUtil.doGet(url, null,getCookie() );
        List<WaybillDto2> list = getDetailData(response);
        return list;
    }

    /**
     *  获取详情数据
     * @param response
     * @throws ParseException
     */
    private  List<WaybillDto2> getDetailData(String response) throws ParseException {
        List<WaybillDto2> counts = new ArrayList<>();
        if(StringUtils.isNotEmpty(response)){
            JSONObject jsonObject = JSONObject.parseObject(response);
            JSONArray data = jsonObject.getJSONArray("data");
            logger.info("数据条目："+data.size());
            if(data!=null && data.size()>0){
                getWaybillDetailByList(data,counts);
                return counts;
            }
        }else{
            logger.error("获取运单列表失败！。。。。。。。。。。。。。。。。。。。。");
            return null;
        }
        return null;
    }



    /**
     * 获取运单详情
     * @param waybillid
     * @throws ParseException
     */
    public  WaybillDto2 getWaybillDetail(String waybillid) throws ParseException {
        String url = "https://apit.y2t.com/lhk/proxy/waybillmanagement/getWayBillDetail?wayBillId="+waybillid+"&_="+new Date().getTime();
        String response = HttpClientUtil.doGet(url, null, getCookie());
        JSONObject json = JSONObject.parseObject(response);
        WaybillDto2 build = new WaybillDto2();

        // 货物类型 相关
        build.setTrackId(json.getString("waybillNo"));
        build.setWaybillCreateTime(json.getString("createdTime").substring(0,19).replaceAll("T"," "));
        build.setGoodsName(json.getString("goodsName"));
        build.setGoodsAmount(getGoodsUnit(json.getString("totalNumberOfUnits"),json.getString("totalVolume"),json.getString("totalWeight")).split(",")[0]);
        build.setGoodsType(GoodsTypeEnum.getDescByCode(json.getString("goodsTypeCode")));
        build.setBussinessType(BussinessEnum.getDescByCode(json.getString("bussinessCode")));
        build.setProjectName(json.getString("projectName"));
        String goodsUnits = getGoodsUnit(json.getString("totalNumberOfUnits"),json.getString("totalVolume"),json.getString("totalWeight")).split(",")[1];
        build.setGoodsUnits(goodsUnits);

        // 托运相关 ：地址，联系人，单位
        JSONArray wayBillCustomerRoutesArray = json.getJSONArray("wayBillCustomerRoutes");
        for (int i = 0; i < wayBillCustomerRoutesArray.size(); i++) {
            JSONObject wayBillCustomerRoutesObj = (JSONObject)wayBillCustomerRoutesArray.get(i);
            String province="",city="",county="",units="",contacts="",contactsPhone="",detailAddr="";
            String routePointAddress = wayBillCustomerRoutesObj.getString("routePointAddress");
            if(StringUtils.isNotEmpty(routePointAddress)){
                String[] address = routePointAddress.split(" ");
                province=address[0];
                if(address.length==2){
                    city=address[1];
                }else if(address.length==3){
                    city=address[1];
                    county=address[2];
                }
            }
            units=json.getString("customerName");
            contacts=json.getString("customerLinkMan");
            contactsPhone=json.getString("customerLinkPhone");
            detailAddr=json.getString("routePointAddressDetail");

            // 托运相关
            if(wayBillCustomerRoutesObj.getString("customerType").equals("1")){
                build.setTyProvince(province);
                build.setTyCity(city);
                build.setTyCounty(county);
                build.setTyUnits(units);
                build.setTyContacts(contacts);
                build.setTyContactsPhone(contactsPhone);
                build.setTyDetailAddr(detailAddr);
            }
            // 收货相关
            if(wayBillCustomerRoutesObj.getString("customerType").equals("2")){
                build.setShProvince(province);
                build.setShCity(city);
                build.setShCounty(county);
                build.setShUnits(units);
                build.setShContacts(contacts);
                build.setShContactsPhone(contactsPhone);
                build.setShDetailAddr(detailAddr);
            }
        }

        // 费用相关
        build.setTotal(json.getString("planPriceAmt"));
        build.setHd(json.getString("receiptMoney"));
        build.setYf(json.getString("sendMoney"));
        build.setDf(json.getString("toPayment"));

        // 运单状态相关
        JSONArray wayBillOperateStatusesArray = json.getJSONArray("wayBillOperateStatuses");
        if(StringUtils.isNotEmpty(json.getString("startTime"))){
            build.setShipmentStartTime(json.getString("startTime").substring(0,19).replaceAll("T"," ")); // 起运时间
        }
        if(wayBillOperateStatusesArray!=null && wayBillOperateStatusesArray.size()>0){
            for (int i = 0; i < wayBillOperateStatusesArray.size(); i++) {
                JSONObject wayBillOperateStatusesObj = (JSONObject)wayBillOperateStatusesArray.get(i);
                if(wayBillOperateStatusesObj.getString("status").equals("2") && wayBillOperateStatusesObj.getString("waybillType").equals("0")){ // 已到达
                    build.setShipmentEndTime(wayBillOperateStatusesObj.getString("createdTime").substring(0,19).replaceAll("T"," "));
                }
            }
        }

        // 其他，运单图片，
        JSONArray waybillUploadPicturesArray = json.getJSONArray("waybillUploadPictures");
        if(waybillUploadPicturesArray!=null && waybillUploadPicturesArray.size()>0){
            String pics = "";
            for (int i = 0; i < waybillUploadPicturesArray.size(); i++) {
                JSONObject waybillUploadPicture =(JSONObject) waybillUploadPicturesArray.get(i);
                pics+=(","+waybillUploadPicture.getString("url"));
            }
            if(StringUtils.isNotEmpty(pics)){
                build.setWaybillImg(pics.substring(1));
            }
        }

        // 其他：运单状态
        String shippingStatusCode = json.getString("shippingStatus");
        build.setWaybillStatus(ShippingStatusEnum.getDescByCode(shippingStatusCode));
        build.setRelWaybillId(json.getString("waybillId"));

        Integer corpId = json.getInteger("corpId");
        build.setCompanyId(corpId);
        // 目的是防止有新的公司创建，但是在我们的map中不存在， 所以需要再执行一遍查询所有公司的操作
        if(StringUtils.isEmpty(companyMap.get(corpId))){
            getCompany();
        }
        build.setCompanyName(companyMap.get(corpId));
        //build.setRemark();
        return build;
    }

    /**
     * 获取司机详情
     * @param build
     * @param driverId
     * @throws ParseException
     */
    public  void getDriverDetail(WaybillDto2 build, String driverId) throws ParseException {
        String url = "https://apit.y2t.com/lhk/proxy/transportcapacitypool/getDriverDetails?driverId="+driverId+"&_="+new Date().getTime();
        String response = HttpClientUtil.doGet(url, null, getCookie());
        if(StringUtils.isNotEmpty(response)){
            JSONObject driverJson = JSONObject.parseObject(response);

            // 司机相关
            build.setDriverName(driverJson.getString("driverName"));
            build.setDriverIdCard(StringUtils.isNotEmpty(driverJson.getString("identityCardNo"))?driverJson.getString("identityCardNo"): IDCardUtil.generateID());
            build.setIdCardAddress(StringUtils.isNotEmpty(driverJson.getString("addressLicence"))?driverJson.getString("addressLicence"):IDCardUtil.generateID());
            build.setDriverSex("男");
            build.setDriverNation(StringUtils.isNotEmpty(driverJson.getString("ethnicGroup"))?driverJson.getString("ethnicGroup"):"汉");
            build.setDriverPhone(driverJson.getString("phone"));
            build.setDriverBornDate(UTCToCST(driverJson.getString("birthdayLicence"),"yyyy-MM-dd"));
            build.setIdCardOffice(driverJson.getString("issuanceAuthority"));
            build.setIdCardStartDate(UTCToCST(driverJson.getString("effectiveDate"),"yyyy-MM-dd"));
            build.setIdCardEndDate(UTCToCST(driverJson.getString("discontinueDate"),"yyyy-MM-dd"));
            build.setIdCardFrontImgUrl(driverJson.getString("frontUrl"));
            build.setIdCardBackImgUrl(driverJson.getString("obverseUrl"));
            build.setDriverNationality("中国");
            build.setDrivingCarType(driverJson.getString("licenceClass"));
            build.setDriverLicenseStartDate(UTCToCST(driverJson.getString("licenceValidFrom"),"yyyy-MM-dd"));
            build.setDriverLicenseEndDate(UTCToCST(driverJson.getString("licenceValidTo"),"yyyy-MM-dd"));
            build.setDriverLicenseGetDateFirst(UTCToCST(driverJson.getString("issueDate"),"yyyy-MM-dd"));
            build.setDriverLicenseImgUrl(driverJson.getString("mainUrl"));

            // 车辆相关
            JSONArray vehicleArray = driverJson.getJSONArray("vehicleViews");
            if(vehicleArray.size()>0){
                JSONObject vehicleJson = (JSONObject)vehicleArray.get(0);
                build.setCarNumber(vehicleJson.getString("vehicleNo"));
                build.setCarLength(vehicleJson.getString("insideLength"));
                build.setCarWidth(vehicleJson.getString("insideWidth"));
                build.setCarHeight(vehicleJson.getString("insideHeight"));
                build.setTonnage(vehicleJson.getString("vehicleWeight"));
                build.setCarType(vehicleJson.getString("vehicleTypeName"));
                build.setCarColor(vehicleJson.getString("plateType"));
                build.setCarOwner(vehicleJson.getString("vehicleOwnerName"));
                build.setCarAddress(vehicleJson.getString("vehicleAddress"));
                build.setUserType("运营");
                build.setModel(vehicleJson.getString("vehicleBrand"));
                build.setCarEngineNumber(vehicleJson.getString("engineNumber"));
                build.setCarIdentyCode(vehicleJson.getString("vehicleFrameNumber"));
                build.setEnergyType("柴油");
                build.setRegisterDate(UTCToCST(vehicleJson.getString("vehicleRegisterDate"),"yyyy-MM-dd"));
                build.setIssueDate(UTCToCST(vehicleJson.getString("vehicleIssueDate"),"yyyy-MM-dd"));
                build.setDrivingImgUrl(vehicleJson.getString("vehicleLicMainUrl"));
            }
        }
    }
    /**
     * 根据公司名字获取id
     * @param
     * @return
     */
    private  Integer getCompany(){
        String url = "https://apit.y2t.com/lhk/proxy/sysconfig/PublicInterface/findSysCompanyAll?_="+new Date().getTime();
        String response = HttpClientUtil.doGet(url, null, getCookie());
        try{
            if(StringUtils.isNotEmpty(response)){
                JSONObject jsonObject = JSONObject.parseObject(response);
                if("true".equals(jsonObject.getString("status"))){
                    JSONArray array = jsonObject.getJSONArray("data");
                    if(CollectionUtils.isNotEmpty(array)){
                        companyMap.clear();
                        for (int i = 0; i < array.size(); i++) {
                            JSONObject data = (JSONObject) array.get(i);
                            Integer companyId = data.getInteger("id");
                            String companyName = data.getString("name");
                            companyMap.put(companyId,companyName);
                        }
                    }
                }
            }
        }catch (Exception e){
            return -1;
        }
        return 0;
    }

    /**
     *  从固定点开始，往后抓取所有运单， 用于=====》运易通每新建运单，我们系统实施抓取
     * @param startTime
     * @param endTime
     */
    public void getAllWaybillListByTime(String startTime, String endTime) throws ParseException {
        // 如果当前时间是凌晨1点钟，就睡眠4个小时
        LocalDateTime startLocalDateTime = LocalDateTime.parse(startTime,DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        LocalDateTime endLocalDateTime = LocalDateTime.parse(endTime,DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        LocalDateTime plus4Hours = startLocalDateTime.plusHours(4);
        if(startLocalDateTime.isBefore(endLocalDateTime)){
            if(plus4Hours.isBefore(endLocalDateTime) || plus4Hours.isEqual(endLocalDateTime)){
                String plust4HoursTime = plus4Hours.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
                logger.info("================================================================");
                logger.info("查询开始时间："+startTime+",查询结束时间："+plust4HoursTime);
                List<WaybillDto2> waybillList = getWaybillList(BILLINGSTATUS, startTime, plust4HoursTime);
                if(CollectionUtils.isNotEmpty(waybillList)){
                    send(AutomaticGrab.TOPIC_4_HOURS_BEFORE_WAYBILL,waybillList);
                }
                redisUtil.set(WaybillU.LAST_QUERY_FOR4_TIME,plust4HoursTime);
                if(CollectionUtils.isNotEmpty(waybillList)){
                    sleep(waybillList.size());
                }
                getAllWaybillListByTime(plust4HoursTime,endTime);
            }else{
                logger.info("================================================================");
                logger.info("查询开始时间："+startTime+",查询结束时间："+endTime);
                List<WaybillDto2> waybillList = getWaybillList(BILLINGSTATUS, startTime, endTime);
                send(AutomaticGrab.TOPIC_4_HOURS_BEFORE_WAYBILL,waybillList);
                redisUtil.set(WaybillU.LAST_QUERY_FOR4_TIME,endTime);

                // 每隔3分钟发送请求，避免cookie失效
                ping();

                String currentTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
                getAllWaybillListByTime(endTime,currentTime);
            }
        }
    }

    /**
     * 查询y2t所有公司，避免cookie失效
     */
    public void ping(){
        Integer everySleepSecond = 1000*60*3;
        Integer forTime = 10 ;
        String nextQueryTime = LocalDateTime.now().plusSeconds(everySleepSecond*forTime/1000).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        for (int i = 0; i < forTime; i++) {
            logger.info("正在执行ping..............."+LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))+",下次查询时间为："+nextQueryTime);
            String url = "https://apit.y2t.com/lhk/proxy/sysconfig/PublicInterface/findSysCompanyAll?_="+new Date().getTime();
            String s = HttpClientUtil.doGet(url, null, getCookie());
            try{
                JSONObject.parseObject(s);
            }catch (Exception e){
                try {
                    loginProcessor();
                    return;
                } catch (InterruptedException ex) {
                    ex.printStackTrace();
                }
            }
            try {
                Thread.sleep(everySleepSecond);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 测试接口cookie是否存活
     */
    public void testCookieOnline() throws InterruptedException {
        System.out.println("开始调用更新运单状态方法");
        String url = "https://apit.y2t.com/lhk/proxy/sysconfig/PublicInterface/findSysCompanyAll?_="+new Date().getTime();
        String response = HttpClientUtil.doGet(url, null, getCookie());
        try{
            // 如果转换错误，说明是登录cookie失效，需要重新登录
            JSONObject.parseObject(response);
        }catch (Exception e){
            System.out.println("更新运单状态失败，cookie已失效，准备自动登录");
            loginProcessor();
        }
    }

    /**
     * 登录后置处理
     * @throws InterruptedException
     */
    public void loginProcessor() throws InterruptedException {
        WebDriver driver = getDriver();
        autoLogin(driver);
        setLoginCookie(driver);
        System.out.println("get完毕");
    }

    /**
     * 数据量大的时候，生产者睡眠，让消费者有充足时间进行消费
     * @param size
     */
    public void sleep(Integer size){
        Integer second = size/50;
        if(second>0){
            try {
                Integer all = 10*second*5;
                for (int i = 0; i < all; i++) {
                    System.out.println("正在睡眠第"+(i+1)+"秒，总共有"+all+"秒");
                    Thread.sleep(1000);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }else{
            if(size>0){
                try {
                    for (int i = 0; i < 20; i++) {
                        System.out.println("正在睡眠第"+(i+1)+"秒，总共有20秒");
                        Thread.sleep(1000);
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }

    }

    public String getLastQueryTimeForInvoice(){
        //redisUtil.set(WaybillU.LAST_QUERY_TIME_FOR_INVOICE,"2021-03-23 16:00:00");
        Object obj = redisUtil.get(WaybillU.LAST_QUERY_TIME_FOR_INVOICE);
        if (obj==null){
            String lastTime = "2021-01-01 00:00:00";
            redisUtil.set(WaybillU.LAST_QUERY_TIME_FOR_INVOICE,lastTime);
            return lastTime;
        }else{
            return (String)obj;
        }
    }


    //*******************************************************************************更新发票相关*******************************************************************************
    /**
     * 查询已开票的运单,逻辑是 从固定时间点开始，每次向后查询4小时的运单，一直递归到 指定的结束时间
     * 用于=====>更新运单的开票状态，方便我们系统更新支付记录
     * @param startTime
     * @param endTime
     * @throws ParseException
     */
    public void getOpenedInvoiceWaybill(String startTime, String endTime) throws ParseException {
        LocalDateTime startLocalDateTime = LocalDateTime.parse(startTime,DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        LocalDateTime endLocalDateTime = LocalDateTime.parse(endTime,DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        LocalDateTime plus2Hours = startLocalDateTime.plusHours(2);

        if (plus2Hours.isBefore(endLocalDateTime) || plus2Hours.isEqual(endLocalDateTime)) {

            String plust2HoursTime = plus2Hours.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            logger.info("定时任务获取发票信息,查询开始时间："+startTime+"，查询结束时间："+plust2HoursTime);
            tips = "正在更新发票信息，查询开始时间："+startTime+"，查询结束时间："+plust2HoursTime;
            String url = getFinishedInvoiceWaybillListUrl(startTime, plust2HoursTime);
            String response = HttpClientUtil.doGet(url, null,getCookie());

            // 根据发票列表里面关联的运单，查询该运单的支付记录
            getPaySuccessWaybill(response);

            // 将发票信息投入消息队列
            if(StringUtils.isNotEmpty(response)){
                JSONObject jsonObject = JSONObject.parseObject(response);
                if(jsonObject.getJSONArray("data").size()>0){
                    sendForInvoice(TOPIC_UPDATE_INVOICE,response);
                }
            }
            redisUtil.set(WaybillU.LAST_QUERY_TIME_FOR_INVOICE,plust2HoursTime);

            getOpenedInvoiceWaybill(plust2HoursTime,endTime);
        }else{
            String url = getFinishedInvoiceWaybillListUrl(startTime, endTime);
            String response = HttpClientUtil.doGet(url, null,getCookie());
            getPaySuccessWaybill(response);

            // 将发票信息投入消息队列
            if(StringUtils.isNotEmpty(response)){
                JSONObject jsonObject = JSONObject.parseObject(response);
                if(jsonObject.getJSONArray("data").size()>0){
                    sendForInvoice(TOPIC_UPDATE_INVOICE,response);
                }
            }
            redisUtil.set(WaybillU.LAST_QUERY_TIME_FOR_INVOICE,endTime);
        }
    }

    /**
     * 查询已开票运单
     * @throws ParseException
     */
    public void getPaySuccessWaybill(String response) throws ParseException {
        if(org.apache.commons.lang3.StringUtils.isNotEmpty(response)){
            JSONObject responseJson = JSONObject.parseObject(response);
            JSONArray dataArray = responseJson.getJSONArray("data");
            if(dataArray.size()>0){
                for (int i = 0; i < dataArray.size(); i++) {
                    logger.info("当前查询的发票数量为："+dataArray.size()+"条,正在解析第"+(i+1)+"条发票号");
                    JSONObject entityJson = (JSONObject) dataArray.get(i);
                    JSONArray invoiceInfoToBillList = entityJson.getJSONArray("invoiceInfoToBillList");
                    if(CollectionUtils.isNotEmpty(invoiceInfoToBillList)){
                        for (int i1 =0; i1 < invoiceInfoToBillList.size(); i1++) {
                            logger.info(tips);
                            logger.info("当前查询的发票数量为："+dataArray.size()+"条,第"+(i+1)+
                                    "条发票号里面的运单数量为："+invoiceInfoToBillList.size()+"条,正在执行的是第"+(i1+1)+"条运单");
                            JSONObject waybillObj = (JSONObject) invoiceInfoToBillList.get(i1);
                            String waybillNo = waybillObj.getString("billNo");
                            String waybillResponse="";
                            try{
                                waybillResponse = HttpClientUtil.doGet(getWaybillByWaybillNoUrl(waybillNo), null,getCookie() );
                            }catch (RuntimeException r){
                                r.printStackTrace();
                                continue;
                            }

                            // 查询详情
                            JSONObject jsonObject = JSONObject.parseObject(waybillResponse);
                            JSONArray data = jsonObject.getJSONArray("data");
                            List<WaybillDto2> count = new ArrayList<>();
                            getWaybillDetailByList(data, count);
                            send(AutomaticGrab.TOPIC_FINISHED_PAY,count);
                        }
                    }
                }
            }
        }
    }


    /**
     * 查询已开票的运单列表,长度为1000条
     * @param startTime
     * @param endTime
     * @return
     */
    public String getFinishedInvoiceWaybillListUrl(String startTime, String endTime){
        startTime = UriEncoder.encode(startTime);
        endTime = UriEncoder.encode(endTime);
        return "https://apit.y2t.com/lhk/proxy/invoice/Finance/findInvoiceWithPaginationAll?wordTrackNo=&invoiceStatus=2&createTimeStart="+startTime+"&createTimeEnd="+endTime+"&applyDateStart=&applyDateEnd=&draweeName=&draw=NaN&columns%5B0%5D%5Bdata%5D=0&columns%5B0%5D%5Bname%5D=&columns%5B0%5D%5Bsearchable%5D=true&columns%5B0%5D%5Borderable%5D=false&columns%5B0%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B0%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B1%5D%5Bdata%5D=1&columns%5B1%5D%5Bname%5D=&columns%5B1%5D%5Bsearchable%5D=true&columns%5B1%5D%5Borderable%5D=true&columns%5B1%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B1%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B2%5D%5Bdata%5D=invoiceInfo.invoiceStatus&columns%5B2%5D%5Bname%5D=&columns%5B2%5D%5Bsearchable%5D=true&columns%5B2%5D%5Borderable%5D=false&columns%5B2%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B2%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B3%5D%5Bdata%5D=invoiceInfo.draweeName&columns%5B3%5D%5Bname%5D=&columns%5B3%5D%5Bsearchable%5D=true&columns%5B3%5D%5Borderable%5D=false&columns%5B3%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B3%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B4%5D%5Bdata%5D=invoiceInfo.amt&columns%5B4%5D%5Bname%5D=&columns%5B4%5D%5Bsearchable%5D=true&columns%5B4%5D%5Borderable%5D=false&columns%5B4%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B4%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B5%5D%5Bdata%5D=invoiceInfo.invoiceStatus&columns%5B5%5D%5Bname%5D=&columns%5B5%5D%5Bsearchable%5D=true&columns%5B5%5D%5Borderable%5D=false&columns%5B5%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B5%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B6%5D%5Bdata%5D=invoiceInfo.applyDate&columns%5B6%5D%5Bname%5D=&columns%5B6%5D%5Bsearchable%5D=true&columns%5B6%5D%5Borderable%5D=false&columns%5B6%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B6%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B7%5D%5Bdata%5D=invoiceInfo.createTime&columns%5B7%5D%5Bname%5D=&columns%5B7%5D%5Bsearchable%5D=true&columns%5B7%5D%5Borderable%5D=false&columns%5B7%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B7%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B8%5D%5Bdata%5D=invoiceInfo.invoicer&columns%5B8%5D%5Bname%5D=&columns%5B8%5D%5Bsearchable%5D=true&columns%5B8%5D%5Borderable%5D=true&columns%5B8%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B8%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B9%5D%5Bdata%5D=invoiceInfo.remark&columns%5B9%5D%5Bname%5D=&columns%5B9%5D%5Bsearchable%5D=true&columns%5B9%5D%5Borderable%5D=true&columns%5B9%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B9%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B10%5D%5Bdata%5D=invoiceInfo.invoiceStatus&columns%5B10%5D%5Bname%5D=&columns%5B10%5D%5Bsearchable%5D=true&columns%5B10%5D%5Borderable%5D=false&columns%5B10%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B10%5D%5Bsearch%5D%5Bregex%5D=false&start=0&length="+DATA_LENGTH+"&search%5Bvalue%5D=&search%5Bregex%5D=false&_=1610163636520";
    }

    /**
     *  运单详情url
     * @param waybillNo
     * @return
     */
    public String getWaybillByWaybillNoUrl(String waybillNo){
        return "https://apit.y2t.com/lhk/proxy/waybillmanagement/getWayBills?projectId=&waybillNo="+waybillNo+"&customerSystemCode=&driverName=&shippingStatus=&trackStatus=&payStatus=&billingStatus=&bTime=&eTime=&companyId=&draw=NaN&columns%5B0%5D%5Bdata%5D=0&columns%5B0%5D%5Bname%5D=&columns%5B0%5D%5Bsearchable%5D=true&columns%5B0%5D%5Borderable%5D=false&columns%5B0%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B0%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B1%5D%5Bdata%5D=1&columns%5B1%5D%5Bname%5D=&columns%5B1%5D%5Bsearchable%5D=true&columns%5B1%5D%5Borderable%5D=false&columns%5B1%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B1%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B2%5D%5Bdata%5D=&columns%5B2%5D%5Bname%5D=&columns%5B2%5D%5Bsearchable%5D=true&columns%5B2%5D%5Borderable%5D=false&columns%5B2%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B2%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B3%5D%5Bdata%5D=&columns%5B3%5D%5Bname%5D=&columns%5B3%5D%5Bsearchable%5D=true&columns%5B3%5D%5Borderable%5D=false&columns%5B3%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B3%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B4%5D%5Bdata%5D=&columns%5B4%5D%5Bname%5D=&columns%5B4%5D%5Bsearchable%5D=true&columns%5B4%5D%5Borderable%5D=false&columns%5B4%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B4%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B5%5D%5Bdata%5D=5&columns%5B5%5D%5Bname%5D=&columns%5B5%5D%5Bsearchable%5D=true&columns%5B5%5D%5Borderable%5D=false&columns%5B5%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B5%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B6%5D%5Bdata%5D=6&columns%5B6%5D%5Bname%5D=&columns%5B6%5D%5Bsearchable%5D=true&columns%5B6%5D%5Borderable%5D=false&columns%5B6%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B6%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B7%5D%5Bdata%5D=7&columns%5B7%5D%5Bname%5D=&columns%5B7%5D%5Bsearchable%5D=true&columns%5B7%5D%5Borderable%5D=false&columns%5B7%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B7%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B8%5D%5Bdata%5D=&columns%5B8%5D%5Bname%5D=&columns%5B8%5D%5Bsearchable%5D=true&columns%5B8%5D%5Borderable%5D=false&columns%5B8%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B8%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B9%5D%5Bdata%5D=9&columns%5B9%5D%5Bname%5D=&columns%5B9%5D%5Bsearchable%5D=true&columns%5B9%5D%5Borderable%5D=false&columns%5B9%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B9%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B10%5D%5Bdata%5D=10&columns%5B10%5D%5Bname%5D=&columns%5B10%5D%5Bsearchable%5D=true&columns%5B10%5D%5Borderable%5D=false&columns%5B10%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B10%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B11%5D%5Bdata%5D=11&columns%5B11%5D%5Bname%5D=&columns%5B11%5D%5Bsearchable%5D=true&columns%5B11%5D%5Borderable%5D=false&columns%5B11%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B11%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B12%5D%5Bdata%5D=&columns%5B12%5D%5Bname%5D=&columns%5B12%5D%5Bsearchable%5D=true&columns%5B12%5D%5Borderable%5D=false&columns%5B12%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B12%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B13%5D%5Bdata%5D=remark&columns%5B13%5D%5Bname%5D=&columns%5B13%5D%5Bsearchable%5D=true&columns%5B13%5D%5Borderable%5D=false&columns%5B13%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B13%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B14%5D%5Bdata%5D=waybillNo&columns%5B14%5D%5Bname%5D=&columns%5B14%5D%5Bsearchable%5D=true&columns%5B14%5D%5Borderable%5D=false&columns%5B14%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B14%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B15%5D%5Bdata%5D=projectName&columns%5B15%5D%5Bname%5D=&columns%5B15%5D%5Bsearchable%5D=true&columns%5B15%5D%5Borderable%5D=false&columns%5B15%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B15%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B16%5D%5Bdata%5D=customerSystemCode&columns%5B16%5D%5Bname%5D=&columns%5B16%5D%5Bsearchable%5D=true&columns%5B16%5D%5Borderable%5D=false&columns%5B16%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B16%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B17%5D%5Bdata%5D=driverName&columns%5B17%5D%5Bname%5D=&columns%5B17%5D%5Bsearchable%5D=true&columns%5B17%5D%5Borderable%5D=false&columns%5B17%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B17%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B18%5D%5Bdata%5D=vehicleNo&columns%5B18%5D%5Bname%5D=&columns%5B18%5D%5Bsearchable%5D=true&columns%5B18%5D%5Borderable%5D=false&columns%5B18%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B18%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B19%5D%5Bdata%5D=driverPhone&columns%5B19%5D%5Bname%5D=&columns%5B19%5D%5Bsearchable%5D=true&columns%5B19%5D%5Borderable%5D=false&columns%5B19%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B19%5D%5Bsearch%5D%5Bregex%5D=false&start=0&length=6&search%5Bvalue%5D=&search%5Bregex%5D=false&_=1610162137126";
    }

    /**
     * 生产  发票信息
     * @param topicName
     * @param msg
     */
    public void sendForInvoice(String topicName,String msg){
        stringRedisTemplate.convertAndSend(topicName, msg);
    }



    // **********************************************************************更新三天内的运单状态************************************************************

    /**
     * 查询前面3天内的运单
     * @param startTime
     * @param endTime
     * @throws ParseException
     */
    public void uploadWaybillStatusIn3Days(String startTime,String endTime) throws ParseException {
        LocalDateTime startLocalDateTime = LocalDateTime.parse(startTime,DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        LocalDateTime endLocalDateTime = LocalDateTime.parse(endTime,DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        LocalDateTime plus4Hours = startLocalDateTime.plusHours(4);
        if(startLocalDateTime.isBefore(endLocalDateTime)){
            if(plus4Hours.isBefore(endLocalDateTime) || plus4Hours.isEqual(endLocalDateTime)){
                String plust4HoursTime = plus4Hours.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
                logger.info("================================================================");
                logger.info("正在更新运单状态：查询开始时间："+startTime+",查询结束时间："+plust4HoursTime);
                List<WaybillDto2> waybillList = getWaybillList(BILLINGSTATUS, startTime, plust4HoursTime);
                if(CollectionUtils.isNotEmpty(waybillList)){
                    send(AutomaticGrab.TOPIC_UPDATE_STATUS_IN_3DAYS,waybillList);
                }
                //redisUtil.set(WaybillU.LAST_QUERY_FOR_UPDATE_STATUS,plust4HoursTime);
                if(CollectionUtils.isNotEmpty(waybillList)){
                    sleep(waybillList.size());
                }
                uploadWaybillStatusIn3Days(plust4HoursTime,endTime);
            }else{
                logger.info("================================================================");
                logger.info("查询开始时间："+startTime+",查询结束时间："+endTime);
                List<WaybillDto2> waybillList = getWaybillList(BILLINGSTATUS, startTime, endTime);
                send(AutomaticGrab.TOPIC_UPDATE_STATUS_IN_3DAYS,waybillList);
                //redisUtil.set(WaybillU.LAST_QUERY_FOR_UPDATE_STATUS,endTime);
            }
        }
    }





    //*******************************************************************公共模块*******************************************************************
    /**
     * 根据运单列表查询运单详情
     * @param data
     * @param counts
     * @return
     * @throws ParseException
     */
    public List<WaybillDto2> getWaybillDetailByList(JSONArray data,List<WaybillDto2> counts) throws ParseException {
        for (int i = 0; i < data.size(); i++) {
            JSONObject waybillJson = (JSONObject)data.get(i);
            getWaybillDetail(waybillJson,counts,i);
        }
        return counts;
    }
    public void getWaybillDetail(JSONObject waybillJson,List<WaybillDto2> counts,int i) throws ParseException {
        // 获取运单详情
        WaybillDto2 waybillDto = getWaybillDetail(waybillJson.getString("waybillId"));

        // 获取司机详情
        getDriverDetail(waybillDto,waybillJson.getString("driverId"));

        // 获取支付信息
        getPayDetail(waybillJson.getString("waybillId"),waybillDto);

        counts.add(waybillDto);
        logger.info("已经获取第"+(i+1)+"条数据,运单号为："+ waybillDto.getTrackId());
    }



    public WaybillDto2 getWaybillDetail(String waybillId,String driverId,String createBy) throws ParseException {
        // 获取运单详情
        WaybillDto2 waybillDto = getWaybillDetail(waybillId);

        // 获取司机详情
        getDriverDetail(waybillDto,driverId);

        // 获取支付信息
        // getPayDetail(waybillId,waybillDto);

       // counts.add(waybillDto);
        waybillDto.setCreateBy(createBy);
        return waybillDto;
    }

    /**
     * 根据文件里面的运单id，查询详情
     */
    public void getWaybillInfoByWaybillId(List<WaybillDto2> counts) throws ParseException {

        String[] fileNames = new String[]{"捷安兴项目.txt","闽商项目.txt","神运项目.txt","意驰项目.txt"};
        for (String fileName : fileNames) {
            System.out.println();
            System.out.println("-----------------------------"+fileName+"执行开始-----------------------------");
            String jsonString = readFileContent("E:\\运易通未支付运单\\林志远2\\"+fileName);
            JSONArray jsonObjects = JSONObject.parseObject(jsonString).getJSONArray("data");
            List<String> pros = new ArrayList<>();
            for (int i = 0 ; i<jsonObjects.size();i++){
                System.out.println("--------------------正在执行第："+(i+1)+"条数据-----------------------------");
                JSONObject jo = jsonObjects.getJSONObject(i);
                JSONObject op =  jo.getJSONArray("wayBillOperateStatuses").getJSONObject(0);
                System.out.println(jo.getInteger("waybillId")+"\t"+jo.getString("waybillNo")+"\t"+op.getInteger("createdUserId")+"\t"+op.getString("createdUserNickname")+"\t"+jo.getString("driverId"));
                String pro =  jo.getString("projectId")+"\t"+jo.getString("projectName")+"\t"+op.getInteger("createdUserId")+"\t"+op.getString("createdUserNickname");
                if(!pros.contains(pro)){
                    pros.add(pro);
                }
                WaybillDto2 waybillDetail = getWaybillDetail(jo.getString("waybillId"), jo.getString("driverId"),op.getString("createdUserId"));
                waybillDetail.setCreateUserName(op.getString("createdUserNickname"));
                List<WaybillDto2> sendList = Arrays.asList(waybillDetail);
                send(TOPIC_GET_WAYBILL_BY_ID,sendList);
                System.out.println("--------------------第："+(i+1)+"条数据发送完毕-----------------------------");
            }
            System.out.println("-----------------------------"+fileName+"执行完毕-----------------------------");
            System.out.println();
        }


    }
    public static String readFileContent(String fileName) {
        File file = new File(fileName);
        BufferedReader reader = null;
        StringBuffer sbf = new StringBuffer();
        try {
            reader = new BufferedReader(new FileReader(file));
            String tempStr;
            while ((tempStr = reader.readLine()) != null) {
                sbf.append(tempStr);
            }
            reader.close();
            return sbf.toString();
        } catch ( Exception e) {
            e.printStackTrace();
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
        }
        return sbf.toString();
    }


    /**
     * 获取下一天
     * @param currentDay
     * @return
     */
    private String getNextDay(String currentDay){
        currentDay = currentDay.substring(0,10);
        LocalDate parse = LocalDate.parse(currentDay, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        LocalDate localDate = parse.plusDays(1);
        return  localDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
    }


    /**
     * 获取cookie
     * @return
     */
    public String getCookie(){
        Object obj = redisUtil.get("y2tLoginCookie");
        if(obj==null){
            return "";
        }else{
            return (String)obj;
        }
    }

    /**
     *
     * @param totalNumberOfUnit  totalNumberOfUnit 件
     * @param   totalVolume 方
     * @param totalWeight 吨
     * @return
     */
    public static String getGoodsUnit(String  totalNumberOfUnit,String totalVolume,String totalWeight){
        if(Convert.toDouble(totalNumberOfUnit)>0){
            return Convert.toLong(totalNumberOfUnit)+",件";
        }
        if(Convert.toDouble(totalWeight)>0){
            return Convert.toLong(totalWeight)+",吨";
        }
        if(Convert.toDouble(totalVolume)>0){
            return Convert.toLong(totalVolume)+",方";
        }
        return "0.0,吨";
    }


    public void send(String topicName,List<WaybillDto2> data){
        String message = JSONObject.toJSONString(data);
        stringRedisTemplate.convertAndSend(topicName, message);
    }


    public static void sendkeys(String sts, WebElement we) throws InterruptedException {
        char[] s = sts.toCharArray();
        for (char ss : s) {
            we.sendKeys(String.valueOf(ss));
            Thread.sleep(200);
        }
    }

    public static String UTCToCST(String UTCStr, String format) throws ParseException {
        if(StringUtils.isEmpty(UTCStr)){
            return "";
        }
        Date date = null;
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        date = sdf.parse(UTCStr);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR, calendar.get(Calendar.HOUR) + 8);
        return sdf.format(calendar.getTime());
    }

    /**
     *
     * @param screenshot
     * @param element
     * @return
     */
    public static File captureElement(File screenshot, WebElement element){
        try {
            BufferedImage img = ImageIO.read(screenshot);
            int width = element.getSize().getWidth();
            int height = element.getSize().getHeight();
            //获取指定元素的坐标
            Point point = element.getLocation();
            //从元素左上角坐标开始，按照元素的高宽对img进行裁剪为符合需要的图片
            BufferedImage dest = img.getSubimage(point.getX(), point.getY(), width, height);
            ImageIO.write(dest, "png", screenshot);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return screenshot;
    }
}
